Computer systems that utilize virtual memory systems are able to simulate more main memory than actually exists as long as there is sufficient disk storage space. When a program runs on such computer systems, the program is broken into segments or pages and the virtual memory system brings these pages from disk storage into the main memory as they are used by the program. As portions of the program are completed, pages are swapped. The system keeps track of which pages are in use and which have been modified.
Currently, in a virtual memory system, whenever a microprocessor executes user-level code, the microprocessor must perform a system call in order to pass commands specific to a peripheral hardware device to that device. These commands contain both functions or operations (e.g., read or write operations) and virtual addresses specific to those functions (e.g., address locations in memory where those read or write operations are to occur).
User-level code cannot simply pass the virtual address to the peripheral device in most situations because most peripheral hardware devices utilize physical addressing and have no way of converting the virtual address into a physical address. If the virtual address were passed, data would be written to or read from the wrong location or no operation would occur at all (in cases where a fault was returned). Accordingly, the code executing on a microprocessor will make a system call that converts the virtual addresses within the command into physical addresses, and then pass the command to the peripheral hardware device along with the actual physical addresses.
Additionally, in a virtual memory system which employs memory paging, the memory pages that the virtual addresses correspond with or point to (i.e., those pages which are being used by the peripheral hardware device) must be “pinned down” in order to ensure that they are not swapped out of the main memory while the peripheral device is accessing them. This is particularly important in a symmetric multiprocessing (SMP) environment, where multiple processors have access to and share the same common centralized main memory system. It is important that any page not be swapped out until all peripheral accesses have completed.
For example, a microprocessor may execute user-level code which requires an Ethernet/network card to retrieve some data from several different virtual address locations (which correspond with actual physical address locations in the memory) and pass that data out over the network to which the computer system is connected. When this is encountered in user-level code, the peripheral hardware device must receive physical addresses in order to perform the data send command. Accordingly, whenever this function is encountered in user-level code, the microprocessor will perform a system call in order to convert the virtual addresses in the instruction set into physical addresses. These physical addresses are then passed to the peripheral device so that the peripheral device knows where (which physical addresses) to access the data from in the memory. Therefore, in this example, the virtual address locations from which the data is to be retrieved must be converted into actual physical address locations in the memory so the physical addresses can be transfer red to the peripheral hardware device (in this case, the Ethernet card). Moreover, the memory pages that correspond with the virtual address locations must be “pinned down” in order to ensure that they are not swapped out while the ethernet card is accessing them.
Performing system calls incurs high overhead and can significantly delay processing. As networking becomes more pervasive and network access to virtual memory occurs more frequently, the cost and overhead of performing system calls during each network access to the virtual memory becomes increasingly taxing on overall system performance.
One solution to this problem which has been implemented in the prior art is to assign blocks of memory locations to user code and to configure a memory controller with the ability to convert the virtual address locations into actual physical address locations. In this proposal, a block of physical addresses is assigned to a process which is executing at the user code level, and this block of physical addresses is mapped into the virtual addresses used by that process. These addresses are then stored in a table which is accessed by the memory controller in order to convert virtual addresses to physical addresses. Any peripheral device access requested by this process must come from this specially configured memory block, which is only a small subset of the process's total virtual address space. This solution requires that continuous blocks be assigned per application or process in order to ensure reliability and accuracy. The table cannot be updated as processes are running except at significant overhead cost, so in general, all possible virtual address locations that may be accessed must be loaded into the table. However, since any one application may access data from many different virtual address locations, it is hard to gauge the size of each block which must be assigned. Moreover, this approach will not work in existing TCP/IP applications where addresses to be accessed by a peripheral device like an Ethernet card are assigned from the full virtual address space rather than a specially configured subset of the virtual address space.
Accordingly, what is needed is a way to convert virtual addresses to physical addresses at the user code level without requiring system calls to convert the addresses to physical addresses. What is further needed is a means for conveying the translated physical address to the peripheral device while guaranteeing that the physical address is indeed one to which that user-level job or function is permitted access. What is further needed to convey the translated physical address to the peripheral device is to place that information onto the data portion of a bus transaction addressed to the peripheral device. What is further needed is a way to ensure that the page where the physical address is located can be “pinned down” once it has been accessed by a peripheral device, so that it is not swapped out until the device is finished using the pages.